import axios from "axios";
import { Message } from "element-ui"; //引入 element-ui 解构 Message 提示信息
import store from "@/store"; // 导入 vuex 获取 token
import { getTimeStamp, removeTimeStamp } from "@/utils/auth"; // 获取 token 时本地缓存的时间
import router from "@/router";

// 定义一个超时时间
const TimeOut = 3600;

// 创建实例
const service = axios.create({
  // 基地址
  baseURL: process.env.VUE_APP_BASE_API,
  // 请求 超过 5000 就请求失败
  timeout: 5000,
});

// 请求拦截器  也有两个函数参数 config，error
service.interceptors.request.use(
  (config) => {
    // 有 token
    if (store.getters.token) {
      // 再注入 token 的这里进行超时判断
      // 如果超时
      if (IsCheckTimeOut()) {
        // 调用  登出的方法
        store.dispatch("user/logout");
        // 删除 缓存内的 时间
        removeTimeStamp();
        // 跳转至登录页面
        router.push("/login");
        // 提示信息
        return Promise.reject(new Error("token 过期了"));
      }
      // 给请求头添加注入 token
      config.headers["Authorization"] = `Bearer ${store.getters.token}`;
      // config.headers.Authorization = `Bearer ${store.getters.token}`;
    }
    // 必须要返回 config
    // console.log(config);1
    return config;
  },
  // 错误
  (error) => {
    return Promise.reject(error); // 进入 catch
  }
);

// 响应拦截器  有两个函数参数 response 表示成功， error 则失败
service.interceptors.response.use(
  //成功
  (response) => {
    //  axios 会自动给返回的数据 套上一层 data
    // response 就是返回的数据
    const { success, message, data } = response.data; // 解构 response.data 内的 success：成功, message：提示信息, data：用户token
    if (success) {
      //如果成功
      return data; //直接返回 数据 用户data
    } else {
      // 失败
      Message.error(message); //  error 错误提示信息
      return Promise.reject(new Error(message)); // 错误要进 catch 所以 直接用 Promise.reject
    }
  },
  //失败
  (error) => {
    // 处理 过期token 被动介入
    // 被动介入会走 响应拦截器 进 Error
    if (
      error.response &&
      error.response.data &&
      error.response.data.code === 10002
    ) {
      // 调用 vuex 登出
      store.dispatch("user/logout");
      // 跳转 登录页
      router.push("/login");
      // 提示错误
      return Promise.reject(new Error("后台说 token 过期了"));
    } else {
      // 提示错误
      Message.error(error.message); // 直接提示错误信息
    }
    // 报错
    return Promise.reject(new Error(error)); // 错误要进 catch 所以 直接用 Promise.reject
  }
);

// 定义一个超时的函数
function IsCheckTimeOut() {
  // 获取当前的时间戳
  const currentTime = Date.now();
  // 取出缓存 的时间戳
  const timeStamp = getTimeStamp();
  // 当前时间戳 - 缓存时间戳 是否 大于 超时时间  return 返回值为 boolean值
  // 大于 则为超时 小于 则没超时
  // (currentTime - timeStamp) / 1000 默认是毫秒 所以要除 1000
  return (currentTime - timeStamp) / 1000 > TimeOut;
}
export default service;
